#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include "rfs-defs.h"

int recibir(PACKAGE *package) {
    return read(package->from, package, sizeof (PACKAGE));
}

int enviar(PACKAGE *package) {
    return write(package->from, package, sizeof (PACKAGE));
}

long segmentar(char * data, PACKAGE * package, unsigned long size) {
    long i = 0;
    for (i = 0; (i * DATA_LENGTH) < size; i++) {
        package->offset = ((i + 1) * DATA_LENGTH) < size ? DATA_LENGTH : (size - (i * DATA_LENGTH));
        memmove(package->data, &data[i * DATA_LENGTH], package->offset);
        if (enviar(package) < 0)
            return ERROR;
    }
    return (i - 1) * DATA_LENGTH + package->offset;
}

long ensamblar(char ** data, PACKAGE * package) {
    int i = 0;
    do {
        if (recibir(package) < 0)
            return ERROR;
        *data = (char *) realloc(*data, i * DATA_LENGTH + package->offset);
        memmove(&(*data)[i * DATA_LENGTH], package->data, package->offset);
        i++;
    } while (package->offset == DATA_LENGTH);
    return (i - 1)*DATA_LENGTH + package->offset;
};

int open_socket(struct sockaddr_in *dir) {
    int sd;

    if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        return (-1);

    if (connect(sd, (struct sockaddr *) dir, sizeof (*dir)) < 0)
        return (-2);

    return sd;
}

int close_socket(int sd) {
    return close(sd);
}